package com.dataseek.iot.core.jwt;
import com.dataseek.iot.core.response.ResponseEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

@Slf4j
public class JwtTokenAuthenticationFilter implements WebFilter {

    public static final String HEADER_PREFIX = "Bearer ";

    private final JwtTokenProvider tokenProvider;

    public JwtTokenAuthenticationFilter(JwtTokenProvider tokenProvider) {
        this.tokenProvider = tokenProvider;
    }

//    @Override
//    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
//        String token = resolveToken(exchange.getRequest());
//        if (StringUtils.hasText(token) && this.tokenProvider.validateToken(token)) {
//            Authentication authentication = this.tokenProvider.getAuthentication(token);
//            return chain.filter(exchange)
//                    .subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));
//        }
//        return chain.filter(exchange);
//    }

    //TODO 改造token验证
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        String token = resolveToken(exchange.getRequest());
        ResponseEntity entity = new ResponseEntity();
        try {
            if (StringUtils.hasText(token) && this.tokenProvider.validateToken(token)) {
                Authentication authentication = this.tokenProvider.getAuthentication(token);
                return chain.filter(exchange)
                        .subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));

            }
        }catch (AuthenticationException e){
            log.error(e.getMessage());
        }
        return chain.filter(exchange);
    }

    private String resolveToken(ServerHttpRequest request) {
        String bearerToken = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(HEADER_PREFIX)) {
            return bearerToken.substring(7);
        }
        return null;
    }
}